package net.imagine.backend.mockrmi.remote.provider.mina.server;

import java.io.IOException;
import java.net.InetSocketAddress;


import net.imagine.backend.mockrmi.util.Constants;


import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSessionConfig;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;
import org.apache.mina.transport.socket.SocketSessionConfig;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;

import net.imagine.backend.mockrmi.remote.server.Server;

/**
 * Mina服务器，包含一个IoAcceptor对象，用于处理客户端的请求
 * 
 * @author wuqh
 * @see IoAcceptor
 */
public class MinaServer implements Server {
	private static  final Log logger = LogFactory.getLog(MinaServer.class);
	private final int port;
	
	private int serviceCount;
	private IoAcceptor acceptor;

	private boolean startuped = false;

	public MinaServer(int port) {
		this.port = port;
	}

	@Override
	public synchronized void startup() {
		// 创建一个acceptor用于接收客户端连接
		acceptor = new NioSocketAcceptor(Constants.SERVER_PROCESSOR_COUNT);

		IoSessionConfig config = acceptor.getSessionConfig();
		if(config instanceof SocketSessionConfig) {
			SocketSessionConfig socketConfig = (SocketSessionConfig) config;
			socketConfig.setSendBufferSize(Constants.SERVER_SEND_BUFFER_SIZE);
			socketConfig.setReceiveBufferSize(Constants.SERVER_RECEIVE_BUFFER_SIZE);
			socketConfig.setKeepAlive(Constants.SERVER_KEEP_ALIVE);
		}
		acceptor.getSessionConfig().setReadBufferSize(Constants.SERVER_READ_BUFFER_SIZE);
		acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, Constants.SERVER_IDLE_SECONDS);

		acceptor.getFilterChain().addLast(Constants.SERVER_CODEC_FILTER_ID,
				new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));

		acceptor.setHandler(new MinaServerIoHandler());
		
		try {
			// 绑定端口
			acceptor.bind(new InetSocketAddress(port));
			logger.debug("server binded to port " + port);
		} catch (IOException e) {
			logger.warn("IOException occurred when startup server", e);
		}

		this.startuped = true;
	}

	/**
	 * {@inheritDoc} 结束服务器线程
	 */
	@Override
	public synchronized void shutdown() {
		if (acceptor == null) {
			return;
		}
		if (this.serviceCount != 0) {
			logger.warn("there was service registed in server, but server will ignore and shutdown");
		}
		// 等待所有线程处理完后关闭
		acceptor.dispose(true);
		logger.debug("server shutdown at port " + port);
		this.startuped = false;
	}

	@Override
	public boolean isStartuped() {
		return startuped;
	}

	@Override
	public synchronized int getServiceCount() {
		return serviceCount;
	}

	@Override
	public synchronized void increaseServiceCount() {
		this.serviceCount++;
	}

	@Override
	public synchronized void decreaseServiceCount() {
		this.serviceCount--;
	}

//	public static void main(String... args) {
//		ServiceRegistry.regist(MockRmiUtils.genId(12345, "mockService"), new test.MockServiceImpl());
//		MinaServer server = new MinaServer(12345);
//		server.startup();
//	}
}
